<?php


namespace Muyuxuan\expressbird;

/**
 * 快递鸟
 */
class ExpressDelivery
{
    protected $config = [
        "user_id"=>"",
        "api_key"=>""
    ];
    protected $domain = 'https://api.kdniao.com/';
    protected $message = "";

    /**
     * 构造函数
     * ExpressDelivery constructor.
     * @param string $userId 用户id
     * @param string $apiKey 用户apikey
     */
    public function __construct(string $userId='',string $apiKey='')
    {
        if(!empty($userId)){
            $this->config['user_id'] = $userId;
        }
        if(!empty($apiKey)){
            $this->config['api_key'] = $apiKey;
        }
    }
    /**
     * 配置
     * ExpressDelivery constructor.
     * @param string $userId 用户id
     * @param string $apiKey 用户apikey
     */
    public function setConfig(string $userId='',string $apiKey=''){
        if(!empty($userId)){
            $this->config['user_id'] = $userId;
        }
        if(!empty($apiKey)){
            $this->config['api_key'] = $apiKey;
        }
    }

    /**
     * 获取签名
     * @param mixed $parameter 字符串或者数组
     * @param bool $hasUtl 是否需要url编码
     * @return string
     */
    protected function getSign($parameter,bool $hasUtl=true){
        if(is_array($parameter)){
            $parameter = json_encode($parameter,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        }
        $str = $parameter.$this->config['api_key'];
        $str =base64_encode(strtolower(md5($str)));
        if($hasUtl){
            $str = urlencode($str);
        }
        return $str;
    }

    /**
     * 请求数据
     * @param string $url 请求地址
     * @param string|array $data 请求数据
     * @param string $RequestType 请求类型
     */
    protected function post(string $url,$data,string $RequestType){
        if(is_array($data)){
            if(empty($data)){
                $newdata = "{}";
            }else{
                $newdata = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
            }
        }else{
            $newdata = $data;
        }
        $allData = [
            'EBusinessID' => $this->config['user_id'],
            'RequestType' =>$RequestType, //免费即时查询接口指令1002/在途监控即时查询接口指令8001/地图版即时查询接口指令8003
            'RequestData' => urlencode($newdata) ,
            'DataType' => '2',
        ];
        $allData['DataSign'] = $this->getSign($newdata);
        $postdata = http_build_query($allData);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $postdata,
                'timeout' => 15 * 60 // 超时时间（单位:s）
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);
        $newresult = json_decode($result,true);
        if($newresult==null){
            $this->message = "请求失败";
            return false;
        }
        return $newresult;
    }

    /**
     * 免费查询订单
     * @param string $ShipperCode 快递公司编码
     * @param string $LogisticCode 快递单号
     * @param string $OrderCode 自定义订单那号
     * @return array
     */
    public function queryFree(string $ShipperCode,string $LogisticCode,string $OrderCode=''){
        $zhici = [
            'STO',
            'YTO',
            'HTKY'
        ];
        if(!in_array($ShipperCode,$zhici)){
            return [false,"只支持申通快递、圆通速递、百世快递"];
        }
        $url = $this->domain."Ebusiness/EbusinessOrderHandle.aspx";
        $data = [
            'ShipperCode'=>$ShipperCode,
            'LogisticCode'=>$LogisticCode,
        ];

        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        $res = $this->post($url,$data,'1002');
        if($res===false){
            return [false,$this->message];
        }
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }

    /**
     *即时查询
     * @param string $ShipperCode 快递公司编码
     * @param string $LogisticCode 快递单号
     * @param string $CustomerName sf参数(寄件人or收件人的手机号码后四位)
     * @param string $OrderCode 自定义订单那号
     * @return array
     */
    public function query(string $ShipperCode,string $LogisticCode,string $CustomerName='',string $OrderCode=''){
        $url = $this->domain."Ebusiness/EbusinessOrderHandle.aspx";
        $data = [
            'ShipperCode'=>$ShipperCode,
            'LogisticCode'=>$LogisticCode,
        ];
        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        if(!empty($CustomerName)){
            $data['CustomerName'] = $CustomerName;
        }
        $res = $this->post($url,$data,'8001');
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }

    /**
     * 查询订单(计费按照次数)
     * @param string $LogisticCode 快递单号
     * @param string $ShipperCode  快递公司
     * @param string $CustomerName sf参数(寄件人or收件人的手机号码后四位)
     * @param string $OrderCode 自定义订单号
     * @return array
     */
    public function queryOrder(string $LogisticCode,string $ShipperCode='',string $CustomerName='',string $OrderCode=''){
        $url = $this->domain."Ebusiness/EbusinessOrderHandle.aspx";
        $data = [
            'LogisticCode'=>$LogisticCode,
        ];
        if(!empty($ShipperCode)){
            $data['ShipperCode'] = $ShipperCode;
        }
        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        if(!empty($CustomerName)){
            $data['CustomerName'] = $CustomerName;
        }
        $res = $this->post($url,$data,'8002');
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }

    /**
     * 查询地图版
     * @param string $ShipperCode 快递公司编号
     * @param string $LogisticCode 快递单号
     * @param string $CustomerName sf参数(寄件人or收件人的手机号码后四位)
     * @param array $Sender 发件地址[ProvinceName:省名称,CityName:市名称，ExpAreaName:区名称,Address:具体地址]
     * @param array $Receiver 收件地址[ProvinceName:省名称,CityName:市名称，ExpAreaName:区名称,Address:具体地址]
     * @param string $OrderCode 自定义单号
     * @param array $event 其他参数
     * @return array
     */
    public function queryMap(string $ShipperCode,string $LogisticCode,string $CustomerName='',string $OrderCode='',array $Sender=[],array $Receiver=[],array $event=[]){
        $url = $this->domain."Ebusiness/EbusinessOrderHandle.aspx";
        $data = [
            'ShipperCode'=>$ShipperCode,
            'LogisticCode'=>$LogisticCode,
        ];
        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        if(!empty($CustomerName)){
            $data['CustomerName'] = $CustomerName;
        }
        if(!empty($Sender)){
            $data['Sender'] = $Sender;
        }
        if(!empty($Receiver)){
            $data['Receiver'] = $Receiver;
        }
        $data = array_merge($data,$event);
        $res = $this->post($url,$data,'8003');
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }

    /**
     * 轨迹订阅免费版
     * @param string $ShipperCode 快递编号
     * @param string $LogisticCode 快递单号
     * @param string $OrderCode 自定义订单号
     * @param array $event 其他参数
     */
    public function SubscriptionTrajectoryFree(string $ShipperCode,string $LogisticCode,string $OrderCode='',array $event=[]){
        $zhici = [
            'STO',
            'YTO',
            'HTKY'
        ];
        if(!in_array($ShipperCode,$zhici)){
            return [false,"免费订阅只支持申通快递、圆通速递、百世快递"];
        }
        $url = $this->domain."api/dist";
        $data = [
            'ShipperCode'=>$ShipperCode,
            'LogisticCode'=>$LogisticCode,
        ];
        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        $data = array_merge($data,$event);
        $res = $this->post($url,$data,'1008');
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }

    /**
     * 轨迹订阅
     * @param string $ShipperCode 快递编号
     * @param string $LogisticCode 快递单号
     * @param string $CustomerName sf参数(寄件人or收件人的手机号码后四位)
     * @param string $OrderCode 自定义订单号
     * @param array $event 其他参数
     * @return array
     */
    public function SubscriptionTrajectory(string $ShipperCode,string $LogisticCode,string $CustomerName='',string $OrderCode='',array $event=[]){
        $url = $this->domain."api/dist";
        $data = [
            'ShipperCode'=>$ShipperCode,
            'LogisticCode'=>$LogisticCode,
        ];
        if(!empty($CustomerName)){
            $data['CustomerName'] = $CustomerName;
        }
        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        $data = array_merge($data,$event);
        $res = $this->post($url,$data,'8008');
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }

    /**
     * 轨迹订阅地图版
     * @param string $ShipperCode 快递公司编码
     * @param string $LogisticCode 快递公司单号
     * @param string $CustomerName sf参数(寄件人or收件人的手机号码后四位)
     * @param array $Sender 发件地址[ProvinceName:省名称,CityName:市名称，ExpAreaName:区名称,Address:具体地址]
     * @param array $Receiver 收件地址[ProvinceName:省名称,CityName:市名称，ExpAreaName:区名称,Address:具体地址]
     * @param string $OrderCode 自定义订单号
     * @param array $event 其他参数
     * @return array
     */
    public function SubscriptionTrajectoryMap(string $ShipperCode,string $LogisticCode,string $CustomerName='',string $OrderCode='',array $Sender=[],array $Receiver=[],array $event=[]){
        $url = $this->domain."api/dist";
        $data = [
            'ShipperCode'=>$ShipperCode,
            'LogisticCode'=>$LogisticCode,
        ];
        if(!empty($CustomerName)){
            $data['CustomerName'] = $CustomerName;
        }
        if(!empty($OrderCode)){
            $data['OrderCode'] = $OrderCode;
        }
        if(!empty($Sender)){
            $data['Sender'] = $Sender;
        }
        if(!empty($Receiver)){
            $data['Receiver'] = $Receiver;
        }
        $data = array_merge($data,$event);
        $res = $this->post($url,$data,'8005');
        if($res===false){
            return [false,$this->message];
        }
        if(!empty($res['Success'])&&$res['Success']==true){
            return [true,$res];
        }else{
            return [false,$res];
        }
    }
}